from pydantic import BaseModel, ConfigDict
import collections
from enum import IntEnum
from typing import Union


class UnitTestConfig_Type(BaseModel):
    pos: str
    name: str
    zh_name: str
    srcAddr: int
    dstAddr: int
    Learmask: int = 0xa5a5a5a5


class UnitTestData_Type(BaseModel):
    name: str
    send: str
    rcev: str


class TestData_Type(BaseModel):
    PosId: str
    MsgId: int
    rcevId: int
    name: str
    Learmask: int = 0xa5a5a5a5
    testDatas: list[UnitTestData_Type] = []
    # DOC 是否自动解锁
    auto_unlock: bool = False


class Uds_Request_Type(BaseModel):
    req_src_addr: int
    req_dst_addr: int
    req_sid: int
    req_param_len: int
    req_data_1: list[int] = []


class Uds_ResponseStatus_Type(IntEnum):
    ZCAN_UDS_ERROR_OK = 0    # 没错误
    ZCAN_UDS_ERROR_TIMEOUT = 1    # 响应超时
    ZCAN_UDS_ERROR_TRANSPORT = 2    # 发送数据失败
    ZCAN_UDS_ERROR_CANCEL = 3    # 取消请求
    ZCAN_UDS_ERROR_SUPPRESS_RESPONSE = 4    # 抑制响应
    ZCAN_UDS_ERROR_BUSY = 5    # 忙碌中
    ZCAN_UDS_ERROR_REQ_PARAM = 6    # 请求参数错误
    ZCAN_UDS_ERROR_OTHTER = 100  # Other


class Uds_ResponseType_Type(IntEnum):
    NEGATIVE = 0
    POSITIVE = 1


class Uds_Positive_Data_Type(BaseModel):
    # DOC 此处配置允许any
    model_config = ConfigDict(arbitrary_types_allowed=True)
    sid: int
    param: list[int]
    param_len: any


class Uds_Negative_Data_Type(BaseModel):
    neg_code: int
    sid: int
    error_code: int


class Uds_Response_Type(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    status: Uds_ResponseStatus_Type
    type: Uds_ResponseType_Type = None
    response: Union[Uds_Positive_Data_Type, Uds_Negative_Data_Type] = None
    reserved: any = None

################################################
# [ ]以下待完善 can 测试的tpye定义
################################################


UnitTestDataStructure = collections.namedtuple(
    "UnitTestDataStructure", ["name", "send", "rcev"]
)


class Can_TestDataStucture_sp:
    """
    每个功能模块测试数据,单元测试用具名元组展示出名称,发送数据,接收数据
    """

    def __init__(
        self, PosId="XY", MsgId=0xFFF, rcevId=0xFFF, name="ModelName", testDatas=None
    ) -> None:
        # TODO: 后面用**kwargs直接拆包方式
        self.PosId = PosId
        self.MsgId = MsgId
        self.rcevId = rcevId
        self.name = name
        self.testDatas = []

        if testDatas is not None:
            for utData in testDatas:
                # cur = UnitTestDataStructure(utData[0], utData[1], utData[2])
                cur = UnitTestData_Type(
                    name=utData[0], send=utData[1], rcev=utData[2])
                self.testDatas.append(cur)

    def toDict(self):
        dictData = {
            "PosId": self.PosId,
            "MsgId": self.MsgId,
            "rcevId": self.rcevId,
            "name": self.name,
            "testDatas": self.testDatas,
        }
        return dictData


class Can_TestDataStucture(BaseModel):
    """
    每个功能模块测试数据,单元测试用具名元组展示出名称,发送数据,接收数据
    """
    PosId: str
    MsgId: int
    rcevId: int
    name: str
    testDatas: list[UnitTestData_Type] = []


class Can_Batc_TestDataStucture(BaseModel):
    """
    每个功能模块测试数据,单元测试用具名元组展示出名称,发送数据,接收数据
    """
    PosId: str
    MsgId: int
    rcevId: int
    name: str
    level: str
    level_signal: str
    testDatas: list[UnitTestData_Type] = []


class CanMsg_std_type(BaseModel):
    id: int
    id_str: str
    data_list: list[int]
    data_list_str: list[str]
    data_str: str


class CanFDMsg_std_type(BaseModel):
    id: int
    id_str: str
    data_list: list[int]
    data_list_str: list[str]
    data_str: str


#######################


# [ ] 待优化为pydantic
AlltestReturnType = collections.namedtuple(
    'AlltestReturnType', ['resFlag', 'resString'])
